package cn.com.cetccst.uicomponents.binding.app;

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelStoreOwner;

import cn.com.cetccst.uicomponents.R;


public abstract class DataBindingActivity<V extends ViewDataBinding> extends AppCompatActivity {

    private ViewModelProvider activityProvider;
    private ViewModelProvider applicationProvider;
    private V binding;

    protected abstract void initViewModel();

    protected abstract DataBindingConfig getDataBindingConfig();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        initViewModel();

        DataBindingConfig dataBindingConfig = getDataBindingConfig();
        if (dataBindingConfig != null && dataBindingConfig.getLayout() > 0) {
            V binding = DataBindingUtil.setContentView(this, dataBindingConfig.getLayout());
            binding.setLifecycleOwner(this);
            if (dataBindingConfig.getStateViewModel() != null) {
                binding.setVariable(dataBindingConfig.getVmVariableId(), dataBindingConfig.getStateViewModel());
            }
            SparseArray bindingParams = dataBindingConfig.getBindingParams();
            for (int i = 0, length = bindingParams.size(); i < length; i++) {
                binding.setVariable(bindingParams.keyAt(i), bindingParams.valueAt(i));
            }
            this.binding = binding;
        }
        View view = findViewById(R.id.toolbar);
        if (view != null) {
            setSupportActionBar((Toolbar) view);
        }
    }

    public V getBinding() {
        return binding;
    }

    protected <T extends ViewModel> T getActivityScopeViewModel(@NonNull Class<T> modelClass) {
        if (activityProvider == null) {
            activityProvider = new ViewModelProvider(this);
        }
        return activityProvider.get(modelClass);
    }

    /**
     * 需要Application实现ViewModelStoreOwner
     *
     * @param modelClass
     * @param <T>
     * @return
     */
    protected <T extends ViewModel> T getApplicationScopeViewModel(@NonNull Class<T> modelClass) {
        if (applicationProvider == null) {
            applicationProvider = new ViewModelProvider((ViewModelStoreOwner) this.getApplicationContext(),
                    getAppFactory(this));
        }
        return applicationProvider.get(modelClass);
    }

    private ViewModelProvider.Factory getAppFactory(Activity activity) {
        Application application = checkApplication(activity);
        return ViewModelProvider.AndroidViewModelFactory.getInstance(application);
    }

    private Application checkApplication(Activity activity) {
        Application application = activity.getApplication();
        if (application == null) {
            throw new IllegalStateException("Your activity/fragment is not yet attached to "
                    + "Application. You can't request ViewModel before onCreate call.");
        }
        return application;
    }
}